/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package bpm.graphic
{
	/*******************************************
	 **** huangjixin,2012-11-15,上午10:10:22 **
	 **** 请一句话表述该类主要作用  **
	 *******************************************/
	import bpm.event.DiagramEditorEvent;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
	import mx.events.CloseEvent;
	import mx.events.DragEvent;
	import mx.managers.DragManager;
	
	import spark.components.Group;
	
	/**
	 * Graph继承自 Group，充当元素的容器。约定所有的元素的容器都命名为“graph”，也就是定义一个名为“graph”的Graph私有变量。
	 * @author huangjixin
	 * 
	 */
	public class Graph extends Group
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 * 定义一个用于拖拽格式的常量：bpmDragDataFormat。 
		 */
		public static const DATA_FORMAT:String = "bpmDragDataFormat";
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		public var cloneFunction:Function;
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 * 构造函数。 
		 * 
		 */
		public function Graph()
		{
			super();
			
			addDragEventListener();
		}//构造函数结束
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		/**
		 * 移除拖拽侦听
		 */
		public function removeDragEventListener():void
		{
			this.removeEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
			this.removeEventListener(DragEvent.DRAG_DROP, dragDropHandler);
		}
		
		/**
		 * 添加拖拽侦听
		 */
		public function addDragEventListener():void
		{
			this.addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
			this.addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
		}
		/**
		 * 判断拖拽的对象是否被该类对象接受。
		 * @param event
		 * 
		 */
		protected function dragEnterHandler(event:DragEvent):void
		{
			if (event.dragSource.hasFormat(Graph.DATA_FORMAT))
			{
				DragManager.acceptDragDrop(UIComponent(event.currentTarget));
				/*var object:Object=event.dragSource.dataForFormat(Graph.DATA_FORMAT);
				var renderer:Renderer=object.cloneRenderer as Renderer;
				if(cloneFunction!=null){
					callLater(cloneFunction,[event.dragInitiator,renderer]);
				}*/
			}
		}
		
		/**
		 * 拖放函数,一旦拖拽对象的鼠标放开，该函数被触发，它将把相应的信息取出，包括拖拽器位置信息等，同时派发DiagramEditorEvent.EDITOR_CREATE事件。
		 * @param event
		 * 
		 */
		protected function dragDropHandler(event:DragEvent):void
		{
			//-------------------
			// 	取出拖拽对象里面的信息，里面有对象纵横坐标偏移量。
			//-------------------
			var object:Object=event.dragSource.dataForFormat(Graph.DATA_FORMAT);
			var classType:String=object.ClassType;
			var hDistance:Number=object.hDistance;
			var vDistance:Number=object.vDistance;
			
			//-------------------
			// 	拖拽器必须继承自己Renderer对象，否则不能拖拽进去Graph容器。
			//-------------------
			if(!event.dragInitiator is Renderer){
				return;
			}
			
			var dragInitiator:Renderer = event.dragInitiator as Renderer;
			var renderer:Renderer=object.cloneRenderer as Renderer;
			var graph:Graph;
			if(renderer.hasOwnProperty("graph")){
				graph = getDeeplistGraph(renderer);
			}else{
				graph = getDeeplistGraph();
			}
			
			
			if(graph){
				graph.addElement(renderer);
				renderer.x = graph.mouseX - hDistance;
				renderer.y = graph.mouseY - vDistance;
			}else{
				addElement(renderer);
				renderer.x=mouseX - hDistance;
				renderer.y=mouseY - vDistance;
			}
			
			invalidateProperties();

			//-------------------
			// 	选择由舞台派发对象。
			//-------------------
			stage.dispatchEvent(new DiagramEditorEvent(DiagramEditorEvent.EDITOR_CREATE,renderer,true));
		}
		
		/**
		 * 找到鼠标所在最深的Graph,如果 currentTarget非空，那么就找到currentTarget下面的Graph对象。
		 * @return 
		 * 
		 */
		public function getDeeplistGraph(currentTarget:Object = null):Graph
		{
			if(!stage){
				return null;
			}
			var array:Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
			var graph:Graph = null;
			for (var j:int = array.length-1; j >=0 ; j--) 
			{
				var object:Object = array[j];
				if(object is Graph){
					graph = object as Graph;
				}
				if(object && object.hasOwnProperty("graph")){
					graph = object["graph"] as Graph;
					
					if(!currentTarget){
						break;
					}else{
						if(object.hasOwnProperty("hostComponent")){
							if(object["hostComponent"] == currentTarget){
								continue;
							}else{
								break;
							}
						}
					}
				}
			}
			return graph;
		}//getDeeplistGraph结束
		
		/**
		 * 获取当前鼠标所在对象。 
		 * @return 
		 * 
		 */
		public function getHitRenderer():Renderer
		{
			if(!stage){
				return null;
			}
			
			var array:Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
			var render:Renderer= null;
			for (var j:int = array.length-1; j >=0 ; j--) 
			{
				var object:Object = array[j];
				if(object.hasOwnProperty("hostComponent")
					&& object["hostComponent"] is Renderer){
					render = object["hostComponent"] as Renderer;
					break;
					
					/*if(object is SkinBase){
					if(object["hostComponent"] is Renderer){
					render = object["hostComponent"] as Renderer;
					break;
					}
					}else if(object.hasOwnProperty("parent")){
					if(object["parent"] is SkinBase){
					var skinBase:SkinBase = object["parent"] as SkinBase;
					if(skinBase["hostComponent"] is Renderer){
					render = skinBase["hostComponent"] as Renderer;
					break;
					}
					}*/
				}
			}
			
			return render;
		}
		/**
		 * 
		 * @param container
		 * @param element
		 * @return 
		 * 
		 */
		public function contain(container:IVisualElementContainer,element:IVisualElement):Boolean
		{
			if(!container || !element){
				return false;
			}
			
			for (var i:int = 0; i < container.numElements; i++) 
			{
				var ele:IVisualElement = container.getElementAt(i);
				if(ele){
					if(ele == element){
						return true;
					}
				}
			}
			return false;
			
		}//contain结束
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		override protected function commitProperties():void{
			super.commitProperties();
		}
	}//类结束
}//包结束